home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
rpg
/
crossfir.92
/
crossfir
/
crossfire-0.92.5
/
server
/
input.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-24
|
53KB
|
1,965 lines
/*
* static char *rcsid_input_c =
* "$Id: input.c,v 1.54 1996/07/24 07:39:18 master Exp master $";
*/
/*
CrossFire, A Multiplayer game for X-windows
Copryight (C) 1994 Mark Wedel
Copyright (C) 1992 Frank Tore Johansen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The author can be reached via e-mail to master@rahul.net
*/
#include <global.h>
#ifndef __CEXTRACT__
#include <sproto.h>
#endif
#include <version.h>
#include <main.h>
#include <spells.h>
#include <newclient.h>
#ifdef SET_TITLE
extern void redraw_title(object *pl);
#endif /* SET_TITLE */
int onoff_value(char *line)
{
int i;
if (sscanf(line, "%d", &i))
return (i != 0);
switch (line[0]) {
case 'o':
switch (line[1]) {
case 'n': return 1; /* on */
default: return 0; /* o[ff] */
}
case 'y': /* y[es] */
case 'k': /* k[ylla] */
case 's':
case 'd':
return 1;
case 'n': /* n[o] */
case 'e': /* e[i] */
case 'u':
default:
return 0;
}
}
/*
* flags:
* 0 - inv & below
* 1 - below & inv
* 2 - inv
* 3 - below
*/
object **find_objects(object *op, char *line, int flags)
{
return NULL;
}
/*
* Check if an item op can be put into a sack. If pl exists then tell
* a player the reason of failure.
* returns 1 if it will fit, 0 if it will not. nrof is the number of
* objects (op) we want to put in. We specify it separately instead of
* using op->nrof because often times, a player may have specified a
* certain number of objects to drop, so we can pass that number, and
* not need to use split_ob and stuff.
*/
int sack_can_hold (object *pl, object *sack, object *op, int nrof) {
char buf[MAX_BUF];
buf[0] = 0;
if (! QUERY_FLAG (sack, FLAG_APPLIED))
sprintf (buf, "%s is not active.", query_name(sack));
if (sack == op)
sprintf (buf, "You can't put %s into itself.", query_name(sack));
if (sack->race && (sack->race != op->race || op->type == CONTAINER
|| (sack->stats.food && sack->stats.food != op->type)))
sprintf (buf, "You can put only %s into %s.", sack->race,
query_name(sack));
if (op->type == SPECIAL_KEY && sack->slaying && op->slaying)
sprintf (buf, "You don't want put the key into %s.", query_name(sack));
if (sack->weight_limit && sack->carrying + (nrof ? nrof : 1) *
op->weight * (100 - sack->stats.Str) / 100 > sack->weight_limit)
sprintf (buf, "That won't fit in %s!", query_name(sack));
if (buf[0]) {
if (pl)
new_draw_info(NDI_UNIQUE, 0,pl, buf);
return 0;
}
return 1;
}
void lock_inv(object *op, object *item) {
SET_FLAG(item,FLAG_INV_LOCKED);
new_draw_info(NDI_UNIQUE, 0,op,"Item has been locked");
draw_inventory(op);
return;
}
void unlock_inv(object *op, object *item) {
CLEAR_FLAG(item,FLAG_INV_LOCKED);
new_draw_info(NDI_UNIQUE, 0,op,"Item has been unlocked");
draw_inventory(op);
return;
}
/* Eneq(@csd.uu.se): Had to remove rotate_right and replace it with a version
which doesn't use insert_ob_in_ob since I redid that to add things last in
the inventory, or next to objects of it's own type. This one now works just
like rotate_left but reversed :-)
[ And now handles invisible objects. Tero.Haatanen@lut.fi ] */
void rotate_right(object *op) {
object *tmp;
char buf[MAX_BUF];
int items=0;
for (tmp=op->inv;tmp;tmp=tmp->below)
if (!tmp->invisible)
items++;
if(items==0) {
new_draw_info(NDI_UNIQUE, 0,op,"You don't carry anything.");
return;
}
if(items==1) {
new_draw_info(NDI_UNIQUE, 0,op,"You only carry one thing.");
return;
}
op->contr->last_used=NULL;
op->contr->last_used_id=0;
for (tmp=op->inv; tmp && tmp->below; tmp=tmp->below);
while(tmp!=NULL&&tmp->invisible)
tmp=tmp->above;
/* tmp points now the last visible item in the inventory */
tmp->above->below=tmp->below;
if (tmp->below)
tmp->below->above=tmp->above;
tmp->above=NULL;
tmp->below=op->inv;
op->inv->above=tmp;
op->inv=tmp;
if(QUERY_FLAG(op, FLAG_WIZ))
sprintf(buf,"The %s (%d) is now on top.",
query_name(op->inv),op->inv->count);
else
sprintf(buf,"The %s is now on top.",query_name(op->inv));
new_draw_info(NDI_UNIQUE, 0,op,buf);
draw_inventory(op);
}
/*
* [ Now rotate_left handles invisible objects too. Tero.Haatanen@lut.fi ]
*/
void rotate_left(object *op) {
object *tmp,*tmp2;
char buf[MAX_BUF];
int items=0;
for (tmp=op->inv;tmp;tmp=tmp->below)
if (!tmp->invisible)
items++;
if(items==0) {
new_draw_info(NDI_UNIQUE, 0,op,"You don't carry anything.");
return;
}
if(items==1) {
new_draw_info(NDI_UNIQUE, 0,op,"You only carry one thing.");
return;
}
op->contr->last_used=NULL;
op->contr->last_used_id=0;
for (tmp=op->inv; tmp && tmp->below; tmp=tmp->below);
for (tmp2=op->inv->below; tmp2 && tmp2->invisible; tmp2=tmp2->below);
tmp2->above->below=NULL;
tmp2->above=NULL;
tmp->below=op->inv;
op->inv->above=tmp;
op->inv=tmp2;
if(QUERY_FLAG(op, FLAG_WIZ))
sprintf(buf,"The %s (%d) is now on top.",
query_name(op->inv),op->inv->count);
else
sprintf(buf,"The %s is now on top.",query_name(op->inv));
new_draw_info(NDI_UNIQUE, 0,op,buf);
draw_inventory(op);
}
void apply_inventory(object *op) {
object *inv;
if(op->contr->last_used!=NULL) {
inv=op->contr->last_used;
if(QUERY_FLAG(inv, FLAG_FREED)||inv->count!=op->contr->last_used_id||
inv->env==NULL||(inv->env!=op&&inv->env->env!=op)) {
op->contr->last_used=NULL;
op->contr->last_used_id=0;
apply_inventory(op);
return;
}
} else {
inv= op->inv;
while(inv&&inv->invisible)
inv=inv->below;
}
if(inv) {
if(!apply(op,inv)) {
new_draw_info_format(NDI_UNIQUE, 0, op,
"I don't know how to apply the %s.",query_name(inv));
}
} else {
new_draw_info(NDI_UNIQUE, 0,op, "You have nothing to apply!");
}
}
void drop_inventory(object *op) {
object *inv,*n=NULL;
if(op->contr->last_used!=NULL) {
inv=op->contr->last_used;
if(QUERY_FLAG(inv, FLAG_FREED)||inv->count!=op->contr->last_used_id||
inv->env==NULL||(inv->env!=op&&inv->env->env!=op)) {
op->contr->last_used=NULL;
op->contr->last_used_id=0;
drop_inventory(op);
return;
}
inv=op->contr->last_used;
if(inv->below!=NULL)
n=inv->below;
else if(inv->above!=NULL)
n=inv->above;
if(n!=NULL) {
op->contr->last_used=n;
op->contr->last_used_id=n->count;
}
} else {
inv=op->inv;
while(inv&&inv->invisible)
inv=inv->below;
}
if(inv)
drop(op,inv);
else
new_draw_info(NDI_UNIQUE, 0,op,"You have nothing to drop!");
}
void examine_monster(object *op,object *tmp) {
object *mon=tmp->head?tmp->head:tmp;
archetype *at=tmp->arch;
if(QUERY_FLAG(mon,FLAG_UNDEAD))
new_draw_info(NDI_UNIQUE, 0,op,"It is an undead force.");
if(mon->level>op->level)
new_draw_info(NDI_UNIQUE, 0,op,"It is likely more powerful than you.");
else if(mon->level<op->level)
new_draw_info(NDI_UNIQUE, 0,op,"It is likely less powerful than you.");
else
new_draw_info(NDI_UNIQUE, 0,op,"It is probably as powerful as you.");
if(mon->attacktype&AT_ACID)
new_draw_info(NDI_UNIQUE, 0,op,"You seem to smell an acrid odor.");
if(tmp->type!=PLAYER)
return;
switch((mon->stats.hp+1)*4/(at->clone.stats.hp+1)) { /* From 1-4 */
case 1:
new_draw_info(NDI_UNIQUE, 0,op,"It is in a bad shape.");
break;
case 2:
new_draw_info(NDI_UNIQUE, 0,op,"It is hurt.");
break;
case 3:
new_draw_info(NDI_UNIQUE, 0,op,"It is somewhat hurt.");
break;
case 4:
new_draw_info(NDI_UNIQUE, 0,op,"It is in excellent shape.");
break;
}
if(present_in_ob(POISONING,mon)!=NULL)
new_draw_info(NDI_UNIQUE, 0,op,"It looks very ill.");
}
char *long_desc(object *tmp) {
static char buf[MAX_BUF];
char *cp;
if(tmp==NULL)
return "";
buf[0]='\0';
switch(tmp->type) {
case RING:
case SKILL:
case WEAPON:
case ARMOUR:
case BRACERS:
case HELMET:
case SHIELD:
case BOOTS:
case GLOVES:
case AMULET:
case GIRDLE:
case BOW:
case ARROW:
case CLOAK:
if(*(cp=describe_item(tmp))!='\0')
sprintf(buf,"%s %s",query_name(tmp),cp);
break;
}
if(buf[0]=='\0')
sprintf(buf,"%s",query_name(tmp));
return buf;
}
void examine(object *op, object *tmp) {
char buf[MAX_BUF];
if (tmp == NULL || tmp->type == CLOSE_CON)
return;
/* Eneq(csd.uu.se): If NO_PRETEXT is defined we should only print the name. */
if (QUERY_FLAG(tmp, FLAG_NO_PRETEXT))
sprintf(buf, "%s.", long_desc(tmp));
else
sprintf(buf, "That is %s.", long_desc(tmp));
new_draw_info(NDI_UNIQUE, 0,op,buf);
buf[0]='\0';
switch(tmp->type) {
case SPELLBOOK:
if(QUERY_FLAG(tmp, FLAG_IDENTIFIED) && tmp->stats.sp > 0 && tmp->stats.sp <= NROFREALSPELLS )
if(!strcmp(tmp->arch->name,"cleric_book"))
sprintf(buf,"%s is a %d level prayer.",
spells[tmp->stats.sp].name,spells[tmp->stats.sp].level);
else
sprintf(buf,"%s is a %d level spell.",
spells[tmp->stats.sp].name,spells[tmp->stats.sp].level);
break;
case BOOK:
if(tmp->msg!=NULL)
strcpy(buf,"Something is written in it.");
break;
case CONTAINER:
if(tmp->race!=NULL)
if(tmp->weight_limit && tmp->stats.Str<100)
sprintf (buf,"It can hold only %s and its weight limit is %.1f kg.",
tmp->race, tmp->weight_limit/(10.0 * (100 - tmp->stats.Str)));
else
sprintf (buf,"It can hold only %s.", tmp->race);
else
if(tmp->weight_limit && tmp->stats.Str<100)
sprintf (buf,"Its weight limit is %.1f kg.",
tmp->weight_limit/(10.0 * (100 - tmp->stats.Str)));
break;
case WAND:
if(QUERY_FLAG(tmp, FLAG_IDENTIFIED))
sprintf(buf,"It has %d charges left.",tmp->stats.food);
break;
}
if(buf[0]!='\0')
new_draw_info(NDI_UNIQUE, 0,op,buf);
if(tmp->material) {
strcpy(buf,"It is made of: ");
if(tmp->material&M_PAPER)
strcat(buf,"paper ");
if(tmp->material&M_IRON)
strcat(buf,"iron ");
if(tmp->material&M_GLASS)
strcat(buf,"glass ");
if(tmp->material&M_LEATHER)
strcat(buf,"leather ");
if(tmp->material&M_WOOD)
strcat(buf,"wood ");
if(tmp->material&M_ORGANIC)
strcat(buf,"organics ");
if(tmp->material&M_STONE)
strcat(buf,"stone ");
if(tmp->material&M_CLOTH)
strcat(buf,"cloth ");
if(tmp->material&M_ADAMANT)
strcat(buf,"adamantite ");
new_draw_info(NDI_UNIQUE, 0,op,buf);
}
if(tmp->weight) {
sprintf(buf,"%s weighs %3.3f kg.", tmp->nrof>1?"They":"It",
(tmp->nrof?tmp->weight*tmp->nrof:tmp->weight)/1000.0);
new_draw_info(NDI_UNIQUE, 0,op,buf);
}
if(tmp->value&&!QUERY_FLAG(tmp, FLAG_STARTEQUIP)) {
if(QUERY_FLAG(tmp, FLAG_UNPAID))
sprintf(buf,"%s would cost you %s.",
tmp->nrof>1?"They":"It",query_cost_string(tmp,op,F_BUY));
else
sprintf(buf,"You would get %s for %s.",
query_cost_string(tmp,op,F_SELL), tmp->nrof>1?"them":"it");
new_draw_info(NDI_UNIQUE, 0,op,buf);
}
if(QUERY_FLAG(tmp, FLAG_MONSTER))
examine_monster(op,tmp);
if(tmp->msg && tmp->type != EXIT && tmp->type != BOOK && tmp->type != CORPSE
&& !QUERY_FLAG(tmp, FLAG_WALK_ON)) {
if (need_identify(tmp) && QUERY_FLAG(tmp, FLAG_IDENTIFIED))
new_draw_info(NDI_UNIQUE, 0,op, "The object has a story:");
#if 0 /* it might not be written on it */
else
new_draw_info(NDI_UNIQUE, 0,op,"Something is written on it:");
#endif
new_draw_info(NDI_UNIQUE, 0,op,tmp->msg);
}
new_draw_info(NDI_UNIQUE, 0,op," "); /* Blank line */
}
/*
* inventory prints object's inventory. If inv==NULL then print player's
* inventory.
* [ Only items which are applied are showed. Tero.Haatanen@lut.fi ]
*/
void inventory(object *op,object *inv) {
object *tmp;
char buf[MAX_BUF], *in;
int items = 0, length;
if (inv==NULL && op==NULL) {
new_draw_info(NDI_UNIQUE, 0,op,"Inventory of what object?");
return;
}
tmp = inv ? inv->inv : op->inv;
while (tmp) {
if ((!tmp->invisible &&
(inv==NULL || inv->type == CONTAINER || QUERY_FLAG(tmp, FLAG_APPLIED)))
|| (!op || QUERY_FLAG(op, FLAG_WIZ)))
items++;
tmp=tmp->below;
}
if (inv==NULL) { /* player's inventory */
if (items==0) {
new_draw_info(NDI_UNIQUE, 0,op,"You carry nothing.");
return;
} else {
length = INFOCHARS-19;
in = "";
if (op)
clear_win_info(op);
new_draw_info(NDI_UNIQUE, 0,op,"Inventory:");
}
} else {
if (items==0)
return;
else {
length = INFOCHARS-21;
in = " ";
}
}
for (tmp=inv?inv->inv:op->inv; tmp; tmp=tmp->below) {
if((!op||!QUERY_FLAG(op, FLAG_WIZ)) && (tmp->invisible ||
(inv && inv->type != CONTAINER && !QUERY_FLAG(tmp, FLAG_APPLIED))))
continue;
if((!op || QUERY_FLAG(op, FLAG_WIZ)))
(void) sprintf(buf,"%s- %-*s (%5d) %-8s", in, length, query_name(tmp),
tmp->count,query_weight(tmp));
else
(void) sprintf(buf,"%s- %-*s %-8s", in, length+8, query_name(tmp),
query_weight(tmp));
new_draw_info(NDI_UNIQUE, 0,op,buf);
}
if(!inv && op) {
sprintf(buf,"%-*s %-8s",
INFOCHARS-9,"Total weight carried:",query_weight(op));
new_draw_info(NDI_UNIQUE, 0,op,buf);
}
}
/*
* look_at prints items on the specifc square.
* [ removed EARTHWALL check and added check for containers inventory.
* Tero.Haatanen@lut.fi ]
*/
void look_at(object *op,int dx,int dy) {
object *tmp;
char buf[MAX_BUF];
int flag=0;
if(op->above!=NULL) {
remove_ob(op);
insert_ob_in_map(op,op->map);
}
if(dx||dy)
for(tmp=get_map_ob(op->map,op->x+dx,op->y+dy);tmp!=NULL&&tmp->above!=NULL;
tmp=tmp->above);
else
tmp=op->below;
while(tmp && (QUERY_FLAG(op, FLAG_WIZ) ||(!tmp->invisible && tmp!=op))) {
if(!flag) {
if(dx||dy)
new_draw_info(NDI_UNIQUE, 0,op,"There you see:");
else {
clear_win_info(op);
new_draw_info(NDI_UNIQUE, 0,op,"You see:");
}
flag=1;
}
if(QUERY_FLAG(op, FLAG_WIZ))
(void) sprintf(buf,"- %s (%d).",query_name(tmp),tmp->count);
else
(void) sprintf(buf,"- %s.",query_name(tmp));
new_draw_info(NDI_UNIQUE, 0,op,buf);
if((tmp->inv!=NULL || (tmp->head && tmp->head->inv)) &&
( (!dx&&!dy) || tmp->type != CONTAINER || QUERY_FLAG(op, FLAG_WIZ)
/* added some cases here -b.t. */
|| !(tmp->type) || tmp->type!=FLESH ))
inventory(op,tmp->head==NULL?tmp:tmp->head);
if(QUERY_FLAG(tmp, FLAG_IS_FLOOR)&&!QUERY_FLAG(op, FLAG_WIZ)) /* don't continue under the floor */
break;
tmp=tmp->below;
}
if(!flag)
if(dx||dy)
new_draw_info(NDI_UNIQUE, 0,op,"You see nothing there.");
else
new_draw_info(NDI_UNIQUE, 0,op,"You see nothing.");
}
void receive_player_name(object *op,char k) {
if(k!=13) {
if((k==8||k==127)&&(op->contr->writing==1))
return;
if(k!=8&&k!=127&&!((k>='a'&&k<='z')||(k>='A'&&k<='Z'))&&k!='-'&&k!='_')
return;
write_ch(op,k);
return;
}
if(op->contr->writing<=1) {
if (op->contr->eric_server>0) get_name(op);
return;
}
if(!check_name(op->contr,op->contr->write_buf+1)) {
get_name(op);
return;
}
if(op->name!=NULL)
free_string(op->name);
op->name=add_string(op->contr->write_buf+1);
new_draw_info(NDI_UNIQUE, 0,op,op->contr->write_buf);
op->contr->last_value= -1; /* Flag: redraw all stats */
draw_stats(op);
op->contr->name_changed=1;
get_password(op);
}
void receive_player_password(object *op,char k) {
if(k!=13) {
if(k!=8&&k!=127&&(!((k>='a'&&k<='z')||(k>='A'&&k<='Z'))||
op->contr->writing>8)) /* Max 8 characters in password */
return;
write_ch(op,k);
return;
}
op->contr->no_echo=0;
if(op->contr->writing<=1) {
remove_lock(op->contr);
get_name(op);
return;
}
op->contr->writing=0;
new_draw_info(NDI_UNIQUE, 0,op," "); /* To hide the password better */
if(op->contr->state==ST_CONFIRM_PASSWORD) {
if(!check_password(op->contr->write_buf+1,op->contr->password)) {
new_draw_info(NDI_UNIQUE, 0,op,"The passwords did not match.");
remove_lock(op->contr);
get_name(op);
return;
}
clear_win_info(op);
display_motd(op);
new_draw_info(NDI_UNIQUE, 0,op," ");
new_draw_info(NDI_UNIQUE, 0,op,"Welcome, Brave New Warrior!");
new_draw_info(NDI_UNIQUE, 0,op," ");
Roll_Again(op);
op->contr->state=ST_ROLL_STAT;
return;
}
strcpy(op->contr->password,crypt_string(op->contr->write_buf+1,NULL));
op->contr->state=ST_ROLL_STAT;
check_login(op);
return;
}
void set_pickup_mode(object *op,int i) {
switch(op->contr->mode=i) {
case 0:
new_draw_info(NDI_UNIQUE, 0,op,"Mode: Don't pick up.");
break;
case 1:
new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up one item.");
break;
case 2:
new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up one item and stop.");
break;
case 3:
new_draw_info(NDI_UNIQUE, 0,op,"Mode: Stop before picking up.");
break;
case 4:
new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up all items.");
break;
case 5:
new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up all items and stop.");
break;
case 6:
new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up all magic items.");
break;
case 7:
new_draw_info(NDI_UNIQUE, 0,op,"Mode: Pick up all coins and gems");
break;
}
}
int explore_mode() {
#ifdef EXPLORE_MODE
player *pl;
for (pl = first_player; pl != (player *) NULL; pl = pl->next)
if (pl->explore)
return 1;
#endif
return 0;
}
/*
* Actual commands.
* Those should be in small separate files (c_object.c, c_wiz.c, cmove.c,...)
*/
static void help_topics(object *op, int what)
{
XDIR *dirp;
struct xdirect *de;
char filename[MAX_BUF], line[80];
int namelen, linelen=0;
switch (what) {
case 1:
sprintf(filename, "%s/wizhelp", LibDir);
new_draw_info(NDI_UNIQUE, 0,op, " Wiz commands:");
break;
case 2:
sprintf(filename, "%s/sockethelp", LibDir);
new_draw_info(NDI_UNIQUE, 0,op, " Socket commands:");
break;
case 3:
sprintf(filename, "%s/mischelp", LibDir);
new_draw_info(NDI_UNIQUE, 0,op, " Misc help:");
break;
default:
sprintf(filename, "%s/help", LibDir);
new_draw_info(NDI_UNIQUE, 0,op, " Commands:");
break;
}
if (!(dirp=xopendir(filename)))
return;
line[0] ='\0';
for (de = xreaddir(dirp, 1); de; de = xreaddir(dirp, 1)) {
namelen = de->d_namlen;
if (namelen <= 2 && *de->d_name == '.' &&
(namelen == 1 || de->d_name[1] == '.' ) )
continue;
linelen +=namelen+1;
if (linelen > 42) {
new_draw_info(NDI_UNIQUE, 0,op, line);
sprintf(line, " %s", de->d_name);
linelen =namelen+1;
continue;
}
strcat(line, " ");
strcat(line, de->d_name);
}
new_draw_info(NDI_UNIQUE, 0,op, line);
xclosedir(dirp);
}
static void show_commands(object *op, int what)
{
char line[80];
int i, size, namelen, linelen=0;
CommArray_s *ap;
extern CommArray_s Commands[], WizCommands[], SocketCommands[];
extern const int CommandsSize, WizCommandsSize, SocketCommandsSize;
switch (what) {
case 1:
ap =WizCommands;
size =WizCommandsSize;
new_draw_info(NDI_UNIQUE, 0,op, " Wiz commands:");
break;
case 2:
ap =SocketCommands;
size = SocketCommandsSize;
new_draw_info(NDI_UNIQUE, 0,op, " Socket commands:");
break;
default:
ap =Commands;
size =CommandsSize;
new_draw_info(NDI_UNIQUE, 0,op, " Commands:");
break;
}
line[0] ='\0';
for (i=0; i<size; i++) {
namelen = strlen(ap[i].name);
linelen +=namelen+1;
if (linelen > 42) {
new_draw_info(NDI_UNIQUE, 0,op, line);
sprintf(line, " %s", ap[i].name);
linelen =namelen+1;
continue;
}
strcat(line, " ");
strcat(line, ap[i].name);
}
new_draw_info(NDI_UNIQUE, 0,op, line);
}
int command_lock (object *op, char *params)
{
objectlink *list;
list = id(op,op->inv,params,0);
if(!list) {
new_draw_info(NDI_UNIQUE, 0,op,"Nothing to lock!");
return 0;
}
op->contr->freeze_inv=1;
op->contr->freeze_look=1;
while(list) {
op->contr->count=list->id;
lock_inv(op,list->ob);
list=list->next;
}
op->contr->freeze_inv=0;
op->contr->count=0;
draw_inventory(op);
return 0;
}
int command_unlock (object *op, char *params)
{
objectlink *list;
list = id(op,op->inv,params,0);
if(!list) {
new_draw_info(NDI_UNIQUE, 0,op,"Nothing to unlock!");
return 1;
}
op->contr->freeze_inv=1;
while(list) {
op->contr->count=list->id;
unlock_inv(op,list->ob);
list=list->next;
}
op->contr->freeze_inv=0;
op->contr->count=0;
draw_inventory(op);
return 0;
}
int command_help (object *op, char *params)
{
struct stat st;
FILE *fp;
char filename[MAX_BUF], line[MAX_BUF];
int len;
if(op != NULL)
clear_win_info(op);
/*
* Main help page?
*/
if (!params) {
sprintf(filename, "%s/def_help", LibDir);
if ((fp=fopen(filename, "r")) == NULL) {
LOG(llevError, "Can't open %s\n", filename);
perror("Can't read default help");
return 0;
}
while (fgets(line, MAX_BUF, fp)) {
line[MAX_BUF-1] ='\0';
len =strlen(line)-1;
if (line[len] == '\n')
line[len] ='\0';
new_draw_info(NDI_UNIQUE, 0,op, line);
}
fclose(fp);
return 0;
}
/*
* Topics list
*/
if (!strcmp(params, "topics")) {
help_topics(op, 3);
if (!op) {
help_topics(op, 2);
if (active_socket->wiz)
help_topics(op, 1);
return 0;
}
help_topics(op, 0);
if (QUERY_FLAG(op, FLAG_WIZ))
help_topics(op, 1);
return 0;
}
/*
* Commands list
*/
if (!strcmp(params, "commands")) {
if (!op) {
show_commands(op, 2);
if (active_socket->wiz)
show_commands(op, 1);
return 0;
}
show_commands(op, 0);
if (QUERY_FLAG(op, FLAG_WIZ))
show_commands(op, 1);
return 0;
}
/*
* User wants info about command
*/
if (strchr(params, '.') || strchr(params, ' ') || strchr(params, '/')) {
sprintf(line, "Illegal characters in '%s'", params);
new_draw_info(NDI_UNIQUE, 0,op, line);
return 0;
}
sprintf(filename, "%s/mischelp/%s", LibDir, params);
if (stat(filename, &st) || !S_ISREG(st.st_mode)) {
if (op) {
sprintf(filename, "%s/help/%s", LibDir, params);
if (stat(filename, &st) || !S_ISREG(st.st_mode)) {
if (QUERY_FLAG(op, FLAG_WIZ)) {
sprintf(filename, "%s/wizhelp/%s", LibDir, params);
if (stat(filename, &st) || !S_ISREG(st.st_mode))
goto nohelp;
} else
goto nohelp;
}
} else {
sprintf(filename, "%s/sockethelp/%s", LibDir, params);
if (stat(filename, &st) || !S_ISREG(st.st_mode)) {
if (active_socket->wiz) {
sprintf(filename, "%s/wizhelp/%s", LibDir, params);
if (stat(filename, &st) || !S_ISREG(st.st_mode))
goto nohelp;
} else
goto nohelp;
}
}
}
/*
* Found that. Just cat it to screen.
*/
if ((fp=fopen(filename, "r")) == NULL) {
LOG(llevError, "Can't open %s\n", filename);
perror("Can't read helpfile");
return 0;
}
sprintf(line, "Help about '%s'", params);
new_draw_info(NDI_UNIQUE, 0,op, line);
while (fgets(line, MAX_BUF, fp)) {
line[MAX_BUF-1] ='\0';
len =strlen(line)-1;
if (line[len] == '\n')
line[len] ='\0';
new_draw_info(NDI_UNIQUE, 0,op, line);
}
fclose(fp);
return 0;
/*
* No_help -escape
*/
nohelp:
sprintf(line, "No help availble on '%s'", params);
new_draw_info(NDI_UNIQUE, 0,op, line);
return 0;
}
int command_chrfont (object *op, char *params)
{
XFontStruct *tmp_font;
if (params != NULL) {
if ((tmp_font=XLoadQueryFont(op->contr->gdisp, params)) != NULL) {
strcpy (op->contr->font_str, params);
XFreeFont(op->contr->gdisp, tmp_font);
} else {
LOG(llevError, "Crossfire: Couldn't load font %s.\n", params);
new_draw_info(NDI_UNIQUE, 0,op, "Couldn't load font.");
}
} else new_draw_info(NDI_UNIQUE, 0,op, "What font?");
return 1;
}
int command_invoke(object *op, char *params)
{
return command_cast_spell(op, params, 'i');
}
int command_cast(object *op, char *params)
{
return command_cast_spell(op, params, 'c');
}
int command_prepare(object *op, char *params)
{
return command_cast_spell(op, params, 'p');
}
/* Some commands are not accepted from sockets */
int command_cast_spell (object *op, char *params, char command)
{
int i, castnow=0;
char *cp=NULL;
char buf[MAX_BUF];
if(!op->contr->nrofknownspells&&!QUERY_FLAG(op, FLAG_WIZ)) {
new_draw_info(NDI_UNIQUE, 0,op,"You don't know any spells.");
return 1;
}
if(op->contr->golem!=NULL) {
remove_friendly_object(op->contr->golem);
remove_ob(op->contr->golem);
free_object(op->contr->golem);
op->contr->golem=NULL;
}
if (command=='i') castnow = 1;
if(params!=NULL) {
int numknown; /* number of spells known by op */
int spnum; /* number of spell that is being cast */
/* rune of fire, rune of ... are special cases */
if (strncmp(params,"rune",4)) {
cp =strstr(params, " of ");
if (cp) {
*cp='\0';
cp +=4;
}
}
if(QUERY_FLAG(op, FLAG_WIZ))
numknown = NROFREALSPELLS;
else
numknown = op->contr->nrofknownspells;
for(i=0;i<numknown;i++){
if (QUERY_FLAG(op, FLAG_WIZ)) spnum = i;
else spnum = op->contr->known_spells[i];
if (!strncmp(params, spells[spnum].name, strlen(params))) {
rangetype orig_rangetype=op->contr->shoottype;
op->contr->shoottype=range_magic;
#ifdef ALLOW_SKILLS
if(op->type==PLAYER&&!QUERY_FLAG(op,FLAG_WIZ)) {
if(!check_skill_to_fire(op)) {
op->contr->shoottype=orig_rangetype;
return 0;
}
}
#endif
if (castnow) {
int value;
/* Need to switch shoottype to range_magic - otherwise
* cast_spell doesn't check to see if the character
* has enough spellpoints.
* Note: now done above this -b.t. */
/* op->contr->shoottype=range_magic; */
value = cast_spell(op,op,op->facing,spnum,0,spellNormal,cp);
op->contr->shoottype=orig_rangetype;
if(spells[spnum].cleric)
op->stats.grace -= value;
else
op->stats.sp -= value;
} else
op->contr->chosen_spell=spnum;
draw_stats(op);
return 1;
/*
op->stats.sp -= invoke_spell(op, op->facing, spnum, 0, spellNormal, cp);
draw_stats(op);
return 1;
*/
}
}
}
new_draw_info(NDI_UNIQUE, 0,op,"Cast what spell? Choose one of:");
new_draw_info(NDI_UNIQUE, 0,op,"[sp] spell name");
if(QUERY_FLAG(op, FLAG_WIZ))
for(i=0;i<NROFREALSPELLS;i++)
{
#ifdef SPELLPOINT_LEVEL_DEPEND
sprintf(buf,"[%02d] %s",SP_level_spellpoint_cost(op,i),
#else
sprintf(buf,"[%02d] %s",spells[i].sp,
#endif
spells[i].name);
new_draw_info(NDI_UNIQUE, 0,op,buf);
}
else
for(i=0;i<(int)op->contr->nrofknownspells;i++)
{
#ifdef SPELLPOINT_LEVEL_DEPEND
sprintf(buf,"[%02d] %s",
SP_level_spellpoint_cost(op,op->contr->known_spells[i]),
#else
sprintf(buf,"[%02d] %s",spells[op->contr->known_spells[i]].sp,
#endif
spells[op->contr->known_spells[i]].name);
new_draw_info(NDI_UNIQUE, 0,op,buf);
}
return 1;
}
#ifdef SET_TITLE
int command_title (object *op, char *params)
{
char buf[MAX_BUF];
if(params == NULL) {
if(op->contr->own_title[0]=='\0')
sprintf(buf,"Your title is '%s'.",
op->contr->title);
else
sprintf(buf,"Your title is '%s'.",
op->contr->own_title);
new_draw_info(NDI_UNIQUE, 0,op,buf);
return 1;
}
if(strcmp(params, "clear")==0 || strcmp(params, "default")==0) {
if(op->contr->own_title[0]=='\0')
new_draw_info(NDI_UNIQUE, 0,op,"Your title is the default title.");
else
new_draw_info(NDI_UNIQUE, 0,op,"Title set to default.");
op->contr->own_title[0]='\0';
redraw_title(op);
return 1;
}
if((int)strlen(params) >= MAX_NAME) {
new_draw_info(NDI_UNIQUE, 0,op,"Title too long.");
return 1;
}
strcpy(op->contr->own_title, params);
redraw_title(op);
return 1;
}
#endif /* SET_TITLE */
int command_save (object *op, char *params)
{
if(save_player(op,1))
new_draw_info(NDI_UNIQUE, 0,op,"You have been saved.");
else
new_draw_info(NDI_UNIQUE, 0,op,"SAVE FAILED!");
return 1;
}
#ifdef SEARCH_ITEMS
int command_search_items (object *op, char *params)
{
char buf[MAX_BUF];
if(params == NULL) {
if(op->contr->search_str[0]=='\0') {
new_draw_info(NDI_UNIQUE, 0,op,"Example: search magic+1");
new_draw_info(NDI_UNIQUE, 0,op,"Would automatically pick up all");
new_draw_info(NDI_UNIQUE, 0,op,"items containing the word 'magic+1'.");
return 1;
}
op->contr->search_str[0]='\0';
new_draw_info(NDI_UNIQUE, 0,op,"Search mode turned off.");
fix_player(op);
draw_stats(op);
return 1;
}
if((int)strlen(params) >= MAX_BUF) {
new_draw_info(NDI_UNIQUE, 0,op,"Search string too long.");
return 1;
}
strcpy(op->contr->search_str, params);
sprintf(buf,"Searching for '%s'.",op->contr->search_str);
new_draw_info(NDI_UNIQUE, 0,op,buf);
fix_player(op);
draw_stats(op);
return 1;
}
#endif /* SEARCH_ITEMS */
int command_peaceful (object *op, char *params)
{
if((op->contr->peaceful=!op->contr->peaceful))
new_draw_info(NDI_UNIQUE, 0,op,"You will not attack other players.");
else
new_draw_info(NDI_UNIQUE, 0,op,"You will attack other players.");
return 1;
}
int command_scroll (object *op, char *params)
{
if((op->contr->scroll=!op->contr->scroll)) {
new_draw_info(NDI_UNIQUE, 0,op,"Scroll is enabled.");
if (op->contr->infofull) {
op->contr->infoline = op->contr->infolines - 1;
draw_all_info(op);
}
}
else {
/* simply put, in scroll mode, infopos does not have to be equal
* to infoline. However, infopos must equal infoline in wrap
* mode. A simple infopos=infoline solves this, but if a redraw
* was needed, the redraw wouldn't look right, so we copy the
* info array to make things right.
* Mark Wedel (master@cats.ucsc.edu)
*/
int i;
char **info;
if ((op->contr->infofull) &&
(op->contr->infoline != op->contr->infopos)){
info = (char **) malloc(sizeof(char *) * op->contr->infolines);
for (i=0; i<(int)op->contr->infolines; i++) {
info[i] = malloc(sizeof(char) * (op->contr->infochars+1));
strncpy(info[i], op->contr->info[(i+op->contr->infopos) % (int)op->contr->infolines],op->contr->infochars);
info[i][op->contr->infochars] = '\0';
}
for (i=0; i<(int)op->contr->infolines; i++)
free(op->contr->info[i]);
free(op->contr->info);
op->contr->info = info;
op->contr->infopos = op->contr->infoline;
draw_all_info(op);
}
new_draw_info(NDI_UNIQUE, 0,op,"Scroll is disabled.");
}
return 1;
}
int command_berzerk (object *op, char *params)
{
if((op->contr->berzerk=!op->contr->berzerk))
new_draw_info(NDI_UNIQUE, 0,op,"Berzerk is enabled.");
else
new_draw_info(NDI_UNIQUE, 0,op,"Berzerk is disabled.");
return 1;
}
int command_strength (object *op, char *params)
{
int i;
if(params==NULL || !sscanf(params, "%d", &i) ||
(!QUERY_FLAG(op, FLAG_WIZ)&&(i<5||i>op->stats.maxsp))) {
new_draw_info(NDI_UNIQUE, 0,op,"Set which strength?");
return 1;
}
op->contr->shootstrength=i;
new_draw_info(NDI_UNIQUE, 0,op,"OK.");
return 1;
}
int command_pickup (object *op, char *params)
{
int i;
if(!params) {
op->contr->count_left=0;
set_pickup_mode(op, (op->contr->mode > 6)? 0: op->contr->mode+1);
return 0;
}
if(params==NULL || !sscanf(params, "%d", &i) || i<0 ) {
new_draw_info(NDI_UNIQUE, 0,op,"Usage: pickup <0-7> or <value_density> .");
return 1;
}
set_pickup_mode(op,i);
return 1;
}
int command_protocol (object *op, char *params)
{
int i;
if (params == NULL || !sscanf(params, "%d", &i)) {
new_draw_info(NDI_UNIQUE, 0,op,"Set what protocol?");
return 1;
}
set_protocol(active_socket, i);
return 1;
}
int command_set (object *op, char *params)
{
if (params == NULL) {
/* Lets tell what options are available */
new_draw_info(NDI_UNIQUE, 0,op, "Options you can set are:");
new_draw_info(NDI_UNIQUE, 0,op, "font: Use normal font mode");
new_draw_info(NDI_UNIQUE, 0,op, "pixmaps: Use pixmaps instead of font");
new_draw_info(NDI_UNIQUE, 0,op, "split: Start in split window mode");
#ifdef Xpm_Pix
new_draw_info(NDI_UNIQUE, 0,op, "xpm: Use X Pixmaps for display");
#endif
return 1;
}
/* Lets not be picky about case */
if(!strcasecmp(params, "font")) {
active_socket->use_pix = 0;
active_socket->color_pix = 0;
new_draw_info(NDI_UNIQUE, 0,op, "OK.");
return 1;
}
if(!strcasecmp(params, "pixmaps")) {
active_socket->use_pix = 1;
active_socket->color_pix = 0;
new_draw_info(NDI_UNIQUE, 0,op, "OK.");
return 1;
}
if(!strcasecmp(params, "split")) {
active_socket->split = 1;
new_draw_info(NDI_UNIQUE, 0,op, "OK.");
return 1;
}
#ifdef Xpm_Pix
if (!strcasecmp(params, "xpm")) {
active_socket->color_pix = 1;
active_socket->use_pix = 0;
new_draw_info(NDI_UNIQUE, 0,op, "OK.");
return 1;
}
#endif
new_draw_info(NDI_UNIQUE, 0,op,"Unknown option.\n");
return 1;
}
int command_unset (object *op, char *params)
{
if (params == NULL) {
new_draw_info(NDI_UNIQUE, 0,op, "Unset what option?");
return 1;
}
if(!strcmp(params,"pixmaps")) {
active_socket->use_pix = 0;
new_draw_info(NDI_UNIQUE, 0,op, "OK.");
return 1;
}
if(!strcmp(params,"split")) {
active_socket->split = 0;
new_draw_info(NDI_UNIQUE, 0,op, "OK.");
return 1;
}
#ifdef Xpm_Pix
if (!strcasecmp(params,"xpm")) {
active_socket->color_pix = 0;
new_draw_info(NDI_UNIQUE, 0,op, "OK.");
return 1;
}
#endif
new_draw_info(NDI_UNIQUE, 0,op,"Unknown option.\n");
return 1;
}
/*
* Now follows non-dm-commands which are also acceptable from sockets
*/
int command_sync (object *op, char *params)
{
int i;
char buf[MAX_BUF];
if (params==NULL || !sscanf(params, "%d", &i)) {
sprintf(buf, "Your current sync is %d.",
#ifdef SERVER
op ? op->contr->sync : active_socket->sync
#else
op->contr->sync
#endif
);
new_draw_info(NDI_UNIQUE, 0,op, buf);
}
#ifdef SERVER
if (!op)
active_socket->sync = i;
else
#endif
op->contr->sync = i;
new_draw_info(NDI_UNIQUE, 0,op,"OK.");
return 1;
}
int command_name (object *op, char *params)
{
if(params == NULL) {
new_draw_info(NDI_UNIQUE, 0,op,"Change name to what?");
return 1;
}
if(op == NULL) {
strncpy(active_socket->name, params, 8);
active_socket->name[8]='\0';
new_draw_info(NDI_UNIQUE, 0,NULL,"OK.");
return 1;
}
new_draw_info(NDI_UNIQUE, 0,op,"You can't change your name.");
return 1;
}
int command_wimpy (object *op, char *params)
{
int i;
char buf[MAX_BUF];
if (params==NULL || !sscanf(params, "%d", &i)) {
sprintf(buf, "Your current wimpy level is %d.", op->run_away);
new_draw_info(NDI_UNIQUE, 0,op, buf);
return 1;
}
sprintf(buf, "Your new wimpy level is %d.", i);
new_draw_info(NDI_UNIQUE, 0,op, buf);
op->run_away = i;
return 1;
}
int command_quit (object *op, char *params)
{
if(op == NULL) {
new_draw_info(NDI_UNIQUE, 0,NULL,"Goodbye.");
active_socket->quit = 1;
return 1;
}
if(op->stats.exp&&!QUERY_FLAG(op, FLAG_WAS_WIZ)) {
new_draw_info(NDI_UNIQUE, 0,op,"This will delete your character!");
new_draw_info(NDI_UNIQUE, 0,op,"Are you still sure you want to quit(y/n)?");
} else
new_draw_info(NDI_UNIQUE, 0,op,"Are you sure you want to quit(y/n)?");
if (op->contr->eric_server>0)
send_query(op->contr->eric_server,CS_QUERY_SINGLECHAR,"");
op->contr->state = ST_CONFIRM_QUIT;
return 1;
}
#ifdef EXPLORE_MODE
/*
* don't allow people to exit explore mode. It otherwise becomes
* really easy to abuse this.
*/
int command_explore (object *op, char *params)
{
/*
* I guess this is the best way to see if we are solo or not. Actually,
* are there any cases when first_player->next==NULL and we are not solo?
*/
if ((first_player!=op->contr) || (first_player->next!=NULL)) {
new_draw_info(NDI_UNIQUE, 0,op,"You can not enter explore mode if you are in a party");
}
else if (op->contr->explore)
new_draw_info(NDI_UNIQUE, 0,op, "There is no return from explore mode");
else {
op->contr->explore=1;
new_draw_info(NDI_UNIQUE, 0,op, "You are now in explore mode");
}
return 1;
}
#endif
#ifdef SOUND_EFFECTS
int command_sound (object *op, char *params)
{
if ((op->contr->rplay_fd = - op->contr->rplay_fd) > 0)
new_draw_info(NDI_UNIQUE, 0,op, "The sounds are enabled.");
else
new_draw_info(NDI_UNIQUE, 0,op, "Silence is golden...");
return 1;
}
#endif
int command_add (object *op, char *params)
{
int i, pixtmp = use_pixmaps, cpix = color_pix;
long splittmp = default_split_window;
int synctmp = synchronize;
char username[9];
#ifdef EXPLORE_MODE
if (explore_mode()) {
new_draw_info(NDI_UNIQUE, 0,op,"You are not able to add new players in explore mode.");
return 1;
}
#endif
#ifdef NO_ADD
if(op != NULL) {
new_draw_info(NDI_UNIQUE, 0,op, "Add is disabled. Use the client.");
return 1;
}
#endif
if(params == NULL) {
if(op != NULL)
op->contr->writing=0;
new_draw_info(NDI_UNIQUE, 0,op,"Add which display?");
return 1;
}
if (active_socket != (sockets *) NULL)
{
color_pix = active_socket->color_pix;
use_pixmaps = (int) active_socket->use_pix;
default_split_window = (long) active_socket->split;
synchronize = active_socket->sync;
strcpy(username, active_socket->name);
}
else
*username = '\0';
i=add_player(params, *username ? username : NULL, NULL,0);
use_pixmaps = pixtmp;
default_split_window = splittmp;
synchronize = synctmp;
color_pix = cpix;
/* This player can be freed during a add_player() */
if(op == NULL || (op->type == PLAYER && !QUERY_FLAG(op,FLAG_FREED)))
new_draw_info(NDI_UNIQUE, 0,op, (i ? errmsg : "OK."));
return 1;
}
int command_shout (object *op, char *params)
{
char buf[MAX_BUF];
if (params == NULL) {
new_draw_info(NDI_UNIQUE, 0,op,"Shout what?");
return 1;
}
if (op == NULL) {
strcpy(buf,active_socket->name);
strcat(buf," shouts: ");
} else {
strcpy(buf,op->name);
strcat(buf," shouts: ");
}
strncat(buf, params, MAX_BUF-30);
buf[MAX_BUF - 1] = '\0';
new_draw_info(NDI_UNIQUE | NDI_ALL | NDI_RED, 1, NULL, buf);
return 1;
}
int command_tell (object *op, char *params)
{
char buf[MAX_BUF],*name = NULL ,*msg = NULL;
player *pl;
#ifdef SERVER
sockets *s;
#endif /* SERVER */
if ( params != NULL){
name = params;
msg = strchr(name, ' ');
if(msg){
*(msg++)=0;
if(*msg == 0)
msg = NULL;
}
}
if( name == NULL ){
new_draw_info(NDI_UNIQUE, 0,op,"Tell whom what?");
return 1;
} else if ( msg == NULL){
sprintf(buf, "Tell %s what?", name);
new_draw_info(NDI_UNIQUE, 0,op,buf);
return 1;
}
if (op == NULL)
sprintf(buf,"%s tells you: %s",active_socket->name,msg);
else
sprintf(buf,"%s tells you: %s",op->name,msg);
for(pl=first_player;pl!=NULL;pl=pl->next)
if(strncasecmp(pl->ob->name,name,MAX_NAME)==0)
{
new_draw_info(NDI_UNIQUE | NDI_WHITE, 0, pl->ob, buf);
return 1;
}
#ifdef SERVER
for(s = first_socket; s != (sockets *) NULL; s = s->next)
if(strncasecmp(s->name,name,MAX_NAME)==0)
{
draw_socket(s->fd,buf);
return 1;
}
new_draw_info(NDI_UNIQUE, 0,op,"No such player or socket.");
#else
new_draw_info(NDI_UNIQUE, 0,op,"No suck player.");
#endif /* SERVER */
return 1;
}
int command_bell (object *op, char *params)
{
char buf[MAX_BUF];
player *pl;
#ifdef SERVER
sockets *s;
#endif /* SERVER */
if (params == NULL) {
new_draw_info(NDI_UNIQUE, 0,op,"Bell whom?");
return 1;
}
for(pl=first_player;pl!=NULL;pl=pl->next)
if(strncasecmp(pl->ob->name, params, MAX_NAME)==0)
{
if (op == NULL)
sprintf(buf,"%s bells you.",active_socket->name);
else
sprintf(buf,"%s bells you.",op->name);
new_draw_info(NDI_UNIQUE, 0,pl->ob,buf);
XBell(pl->ob->contr->gdisp,100);
return 1;
}
#ifdef SERVER
for(s = first_socket; s != (sockets *) NULL; s = s->next)
if(strncasecmp(s->name, params, MAX_NAME)==0)
{
if (op == NULL)
sprintf(buf,"%s bells you.%c",active_socket->name,7);
else
sprintf(buf,"%s bells you.%c",op->name,7);
draw_socket(s->fd,buf);
return 1;
}
#endif /* SERVER */
return 0;
}
/**************************************************************************/
/* Returns TRUE if the range specified (int r) is legal - that is,
* the character has an item that is equipped for that range type.
* return 0 if there is no item of that range type that is usable.
*/
int legal_range(object *op,int r) {
int i;
object *tmp;
switch(r) {
case range_none: /* "Nothing" is always legal */
return 1;
case range_bow: /* bows */
for (tmp=op->inv; tmp!=NULL; tmp=tmp->below)
if (tmp->type == BOW && QUERY_FLAG(tmp, FLAG_APPLIED))
return 1;
return 0;
case range_magic: /* cast spells */
if (op->contr->nrofknownspells == 0)
return 0;
for (i = 0; i < op->contr->nrofknownspells; i++)
if (op->contr->known_spells[i] == op->contr->chosen_spell)
return 1;
op->contr->chosen_spell = op->contr->known_spells[0];
return 1;
case range_wand: /* use wands */
for (tmp=op->inv; tmp!=NULL; tmp=tmp->below)
if (tmp->type == WAND && QUERY_FLAG(tmp, FLAG_APPLIED)) {
if (QUERY_FLAG(tmp, FLAG_BEEN_APPLIED) || QUERY_FLAG(tmp, FLAG_IDENTIFIED))
op->contr->known_spell = 1;
else
op->contr->known_spell = 0;
op->contr->chosen_item_spell=tmp->stats.sp;
return 1;
}
return 0;
case range_rod:
for (tmp=op->inv; tmp!=NULL; tmp=tmp->below)
if (tmp->type == ROD && QUERY_FLAG(tmp, FLAG_APPLIED)) {
if (QUERY_FLAG(tmp,FLAG_BEEN_APPLIED) || QUERY_FLAG(tmp, FLAG_IDENTIFIED))
op->contr->known_spell = 1;
else
op->contr->known_spell = 0;
op->contr->chosen_item_spell=tmp->stats.sp;
return 1;
}
return 0;
case range_horn:
for (tmp=op->inv; tmp!=NULL; tmp=tmp->below)
if (tmp->type == HORN && QUERY_FLAG(tmp, FLAG_APPLIED)) {
if (QUERY_FLAG(tmp,FLAG_BEEN_APPLIED) || QUERY_FLAG(tmp, FLAG_IDENTIFIED))
op->contr->known_spell = 1;
else
op->contr->known_spell = 0;
op->contr->chosen_item_spell=tmp->stats.sp;
return 1;
}
return 0;
case range_scroll: /* Use scrolls */
return 0;
case range_skill:
for (tmp = op->inv; tmp!=NULL; tmp=tmp->below) {
if (tmp->type == SKILL) {
return 1;
}
}
op->chosen_skill=NULL; /* they have lost all skills :) */
return 0;
}
return 0;
}
void change_spell(object *op,char k) {
char buf[MAX_BUF];
if(op->contr->golem!=NULL) {
remove_friendly_object(op->contr->golem);
remove_ob(op->contr->golem);
free_object(op->contr->golem);
op->contr->golem=NULL;
}
do {
op->contr->shoottype += ((k == '+') ? 1 : -1);
if(op->contr->shoottype >= range_size)
op->contr->shoottype = range_none;
else if (op->contr->shoottype <= range_bottom)
op->contr->shoottype = (rangetype) range_size-1;
} while (!legal_range(op,op->contr->shoottype));
switch(op->contr->shoottype) {
case range_none:
strcpy(buf,"No ranged attack chosen.");
break;
case range_bow: {
object *tmp;
for (tmp = op->inv; tmp; tmp = tmp->below)
if (tmp->type == BOW && QUERY_FLAG (tmp, FLAG_APPLIED))
break;
sprintf (buf, "Switched to %s and %s.", query_name(tmp),
tmp && tmp->race ? tmp->race : "nothing");
}
break;
case range_magic:
sprintf(buf,"Switched to spells (%s).",
spells[op->contr->chosen_spell].name);
new_draw_info(NDI_UNIQUE, 0,op,buf);
break;
case range_wand:
sprintf(buf,"Switched to wand (%s).",
op->contr->known_spell ?
spells[op->contr->chosen_item_spell].name : "unknown");
break;
case range_rod:
sprintf(buf, "Switched to rod (%s).",
op->contr->known_spell ?
spells[op->contr->chosen_item_spell].name : "unknown");
break;
case range_horn:
sprintf(buf, "Switched to horn (%s).",
op->contr->known_spell ?
spells[op->contr->chosen_item_spell].name : "unknown");
break;
case range_skill:
sprintf (buf, "Switched to skill: %s", op->chosen_skill ?
op->chosen_skill->name : "none");
break;
default:
break;
}
new_draw_info(NDI_UNIQUE, 0,op,buf);
draw_stats(op);
}
#ifdef SAVE_WINDOW_POSITIONS
void get_window_coord(object *op, Window win,
int *x,int *y,
int *wx,int *wy,
unsigned int *w,unsigned int *h)
{
Window root,child;
unsigned int tmp;
XGetGeometry(op->contr->gdisp,win,
&root,
x,y,w,h,
&tmp,&tmp);
XTranslateCoordinates(op->contr->gdisp,win,root,
0,0,wx,wy,
&child);
}
#endif /* SAVE_WINDOW_POSITIONS */
int command_rotateinventory (object *op, char *params)
{
int size, i, j=1;
object *head, *tail, *tmp;
char buf[MAX_BUF];
if (params && params[0])
sscanf(params, "%d", &j);
if (!j)
return 0;
if(!op->inv) {
new_draw_info(NDI_UNIQUE, 0,op,"You don't carry anything.");
return 0;
}
for (size=0,tmp=op->inv; tmp; tmp=tmp->below)
if (!tmp->invisible)
size++;
if (size < 2) {
new_draw_info(NDI_UNIQUE, 0,op,"You only carry one thing.");
return 0;
}
if (FABS(j) >= size) {
new_draw_info(NDI_UNIQUE, 0,op, "Value too big");
return 0;
}
op->contr->last_used =NULL;
op->contr->last_used_id =0;
if (j<0) {
for (i=0,head=NULL,tmp=op->inv; tmp->below; tmp=tmp->below)
if (!tmp->invisible)
if (i-- == j)
head =tmp;
tail =tmp;
} else {
for (tmp=op->inv; tmp->below; tmp=tmp->below)
;
tail =tmp;
for (i=0; tmp; tmp=tmp->above)
if (!tmp->invisible)
if (++i == j)
break;
head =tmp;
}
if (!head)
return 0;
tmp =op->inv;
op->inv =head;
head->above->below =NULL;
head->above =NULL;
tail->below =tmp;
tmp->above =tail;
if(QUERY_FLAG(op, FLAG_WIZ))
sprintf(buf,"Rotate %d. The %s (%d) is now on top.",
j, query_name(op->inv),op->inv->count);
else
sprintf(buf,"Rotate %d. The %s is now on top.", j, query_name(op->inv));
new_draw_info(NDI_UNIQUE, 0,op,buf);
draw_inventory(op);
op->contr->count_left=0;
return 0;
}
int command_invisible (object *op, char *params)
{
if (!op)
return 0;
op->invisible+=100;
update_object(op);
new_draw_info(NDI_UNIQUE, 0,op,"You turn invisible.");
return 0;
}
int command_rotateshoottype (object *op, char *params)
{
if (!params)
change_spell(op,'+');
else
change_spell(op, params[0]);
return 0;
}
int command_show (object *op, char *params)
{
if(!params) {
if (++op->contr->show_what > show_nonmagical)
op->contr->show_what = show_all;
draw_all_inventory(op);
return 1;
}
if (!strncmp(params, "all", strlen(params)))
op->contr->show_what = show_all;
else if (!strncmp(params, "applied", strlen(params)))
op->contr->show_what = show_applied;
else if (!strncmp(params, "unapplied", strlen(params)))
op->contr->show_what = show_unapplied;
else if (!strncmp(params, "unpaid", strlen(params)))
op->contr->show_what = show_unpaid;
else if (!strncmp(params, "cursed", strlen(params)))
op->contr->show_what = show_cursed;
else if (!strncmp(params, "magical", strlen(params)))
op->contr->show_what = show_magical;
else if (!strncmp(params, "nonmagical", strlen(params)))
op->contr->show_what = show_nonmagical;
draw_all_inventory(op);
return 1;
}
int command_throw (object *op, char *params)
{
new_draw_info(NDI_UNIQUE, 0,op,"Throw is disabled (it was too buggy).");
#if 0
op->contr->shoottype=10;
op->contr->count_left=0;
new_draw_info(NDI_UNIQUE, 0,op,"You will now throw things.");
#endif
return 0;
}
int command_brace (object *op, char *params)
{
if (!params)
op->contr->braced =!op->contr->braced;
else
op->contr->braced =onoff_value(params);
if(op->contr->braced)
new_draw_info(NDI_UNIQUE, 0,op, "You are braced.");
else
new_draw_info(NDI_UNIQUE, 0,op, "Not braced.");
fix_player(op);
return 0;
}
int command_rotatespells (object *op, char *params)
{
player *pl=op->contr;
int i, j;
if(pl->shoottype != range_magic) {
if(pl->nrofknownspells > 0) {
pl->shoottype = range_magic;
pl->chosen_spell = pl->known_spells[0];
} else
new_draw_info(NDI_UNIQUE, 0,op,"You know no spells.");
return 0;
}
for(i=0;i<pl->nrofknownspells;i++)
if(pl->known_spells[i]==pl->chosen_spell)
{
j =1;
if(params)
sscanf(params, "%d", &j);
i +=j + (int)pl->nrofknownspells;
i = i % (int)pl->nrofknownspells;
pl->chosen_spell=pl->known_spells[i];
draw_stats(op);
return 1;
}
pl->chosen_spell=pl->known_spells[0];
draw_stats(op);
return 1;
}
#ifdef SAVE_WINDOW_POSITIONS
int command_savewinpos (object *op, char *params)
{
player *pl=op->contr;
int i,eq=1;
if(!(pl->split_window)) {
new_draw_info(NDI_UNIQUE, 0,op,"You can't save window positions in this mode.");
return 0;
}
if(pl->valid_save_positions) {
pl->valid_save_positions=0;
new_draw_info(NDI_UNIQUE, 0,op,"Window positions will no longer be saved.");
return 0;
}
get_window_coord(op,pl->win_game,
&pl->win_pos[0].x,&pl->win_pos[0].y,
&pl->win_pos[0].wx,&pl->win_pos[0].wy,
&pl->win_pos[0].w,&pl->win_pos[0].h);
get_window_coord(op,pl->win_stats,
&pl->win_pos[1].x,&pl->win_pos[1].y,
&pl->win_pos[1].wx,&pl->win_pos[1].wy,
&pl->win_pos[1].w,&pl->win_pos[1].h);
get_window_coord(op,pl->win_info,
&pl->win_pos[2].x,&pl->win_pos[2].y,
&pl->win_pos[2].wx,&pl->win_pos[2].wy,
&pl->win_pos[2].w,&pl->win_pos[2].h);
get_window_coord(op,pl->win_inv,
&pl->win_pos[3].x,&pl->win_pos[3].y,
&pl->win_pos[3].wx,&pl->win_pos[3].wy,
&pl->win_pos[3].w,&pl->win_pos[3].h);
get_window_coord(op,pl->win_look,
&pl->win_pos[4].x,&pl->win_pos[4].y,
&pl->win_pos[4].wx,&pl->win_pos[4].wy,
&pl->win_pos[4].w,&pl->win_pos[4].h);
get_window_coord(op,pl->win_message,
&pl->win_pos[5].x,&pl->win_pos[5].y,
&pl->win_pos[5].wx,&pl->win_pos[5].wy,
&pl->win_pos[5].w,&pl->win_pos[5].h);
for(i=0;i<5;i++) /* try to figure out the window coords */
if(pl->win_pos[i].x!=pl->win_pos[i+1].x ||
pl->win_pos[i].y!=pl->win_pos[i+1].y)
{
eq=0; /* window positions were different */
return 0;
}
if(eq) /* need to shift window positions (wm frame) */
for(i=0;i<6;i++)
{
#ifdef FUNNY_WINDOW_MANAGER /* try defining this if the other doesn't work */
pl->win_pos[i].x=pl->win_pos[i].wx-
pl->win_pos[i].x;
pl->win_pos[i].y=pl->win_pos[i].wy-
pl->win_pos[i].y;
#else /* FUNNY_WINDOW_MANAGER */
pl->win_pos[i].x=pl->win_pos[i].wx;
pl->win_pos[i].y=pl->win_pos[i].wy;
#endif /* FUNNY_WINDOW_MANAGER */
}
pl->valid_save_positions=1;
new_draw_info(NDI_UNIQUE, 0,op,"Current window positions will be saved.");
return 0;
}
#endif /* SAVE_WINDOW_POSITIONS */